package com.imooc.user.controller;


import com.imooc.pojo.IMOOCJSONResult;
import com.imooc.user.pojo.UserAddress;
import com.imooc.user.pojo.bo.AddressBo;
import com.imooc.user.service.AddressService;
import com.imooc.utils.MobileEmailUtils;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 地址
 *
 * @author 顾志杰
 */
@Api(value = "地址相关",tags = "地址相关的接口")
@RestController
@RequestMapping("address")
public class AddressController {
    private AddressService addressService;
    public AddressController() {

    }
    @Autowired
    public AddressController(AddressService addressService) {
        this.addressService = addressService;
    }
    /**
     * 用户在确认订单页面，可以针对收货地址做以下操作
     * 1.查询用户所有收货地址
     * 2.新增收货地址
     * 3.删除收货地址
     * 4.修改收货地址
     * 5.设置默认收货地址
     */



    @ApiOperation(value = "根据用户id查询收货地址", notes = "根据用户id查询收货地址", httpMethod = "POST")
    @PostMapping("/list")
    @HystrixCommand(
            commandKey = "addressList", // 全局唯一的标识服务，默认函数名称
            groupKey = "address", // 全局服务分组，用于组织仪表盘，统计信息。默认：类名
            fallbackMethod = "addressList", //同一个类里，public private都可以
            // 在列表中的exception，不会触发降级
//            ignoreExceptions = {IllegalArgumentException.class}
            // 线程有关的属性
            // 线程组, 多个服务可以共用一个线程组
            threadPoolKey = "threadPoolA",
            threadPoolProperties = {
                    // 核心线程数
                    @HystrixProperty(name = "coreSize", value = "10"),
                    // coreSize > 0, LinkedBlockingQueue -> 请求等待队列
                    // 默认-1 , SynchronousQueue -> 不存储元素的阻塞队列（建议读源码，学CAS应用）
                    @HystrixProperty(name = "maxQueueSize", value = "40"),
                    // 在maxQueueSize=-1的时候无效，队列没有达到maxQueueSize依然拒绝
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),
                    // （线程池）统计窗口持续时间
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "2024"),
                    // （线程池）窗口内桶子的数量
                    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "18"),
            }
//            ,
//            commandProperties = {
//                  // TODO 熔断降级相关属性，也可以放在这里
//            }
    )
    public IMOOCJSONResult refresh(@ApiParam(name = "userId", value = "用户id", required = true)
                                   @RequestParam String userId) throws InterruptedException {
//        Thread.sleep(5000);
        if (StringUtils.isBlank(userId)){ return IMOOCJSONResult.errorMsg(null);}
        List<UserAddress> userAddresses = addressService.queryAll(userId);
        return IMOOCJSONResult.ok(userAddresses);
    }



    @ApiOperation(value = "新增收货地址", notes = "新增收货地址", httpMethod = "POST")
    @PostMapping("/add")
    public IMOOCJSONResult add(@RequestBody AddressBo addressBo) {
        IMOOCJSONResult imoocjsonResult = checkAddress(addressBo);
        if(imoocjsonResult.getStatus()!=200){return imoocjsonResult;}
        addressService.addNewUserAddress(addressBo);
        return IMOOCJSONResult.ok();
    }


    @ApiOperation(value = "修改收货地址", notes = "修改收货地址", httpMethod = "POST")
    @PostMapping("/update")
    public IMOOCJSONResult update(@RequestBody AddressBo addressBo) {
        IMOOCJSONResult imoocjsonResult = checkAddress(addressBo);
        if(imoocjsonResult.getStatus()!=200){return imoocjsonResult;}
        addressService.updateUserAddress(addressBo);
        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value = "删除收货地址", notes = "删除收货地址", httpMethod = "POST")
    @PostMapping("/delete")
    public IMOOCJSONResult delete(@ApiParam(name = "userId", value = "用户id", required = true)@RequestParam String userId,
                                  @ApiParam(name = "addressId", value = "地址id", required = true)@RequestParam String addressId) {

        if(StringUtils.isBlank(userId)){return IMOOCJSONResult.errorMsg(null);}
        if(StringUtils.isBlank(addressId)){return IMOOCJSONResult.errorMsg(null);}
        addressService.deleteUserAddress(userId,addressId);
        return IMOOCJSONResult.ok();
    }

    @ApiOperation(value = "设置为默认地址", notes = "设置为默认地址", httpMethod = "POST")
    @PostMapping("/setDefalut")
    public IMOOCJSONResult setDefalut(@ApiParam(name = "userId", value = "用户id", required = true)@RequestParam String userId,
                                  @ApiParam(name = "addressId", value = "地址id", required = true)@RequestParam String addressId) {

        if(StringUtils.isBlank(userId)){return IMOOCJSONResult.errorMsg(null);}
        if(StringUtils.isBlank(addressId)){return IMOOCJSONResult.errorMsg(null);}
        addressService.setDefalutUserAddress(userId,addressId);
        return IMOOCJSONResult.ok();
    }

    /**
     * 统一判断addressBo内字段属性
     * @param addressBo 传入参数
     * @return IMOOCJSONResult
     */
    private IMOOCJSONResult checkAddress(AddressBo addressBo) {
        String receiver = addressBo.getReceiver();
        if (StringUtils.isBlank(receiver)) {
            return IMOOCJSONResult.errorMsg("收货人不能为空");
        }
        if (receiver.length() > 12) {
            return IMOOCJSONResult.errorMsg("收货人姓名不能太长");
        }

        String mobile = addressBo.getMobile();
        if (StringUtils.isBlank(mobile)) {
            return IMOOCJSONResult.errorMsg("收货人手机号不能为空");
        }
        if (mobile.length() != 11) {
            return IMOOCJSONResult.errorMsg("收货人手机号长度不正确");
        }
        boolean isMobileOk = MobileEmailUtils.checkMobileIsOk(mobile);
        if (!isMobileOk) {
            return IMOOCJSONResult.errorMsg("收货人手机号格式不正确");
        }

        String province = addressBo.getProvince();
        String city = addressBo.getCity();
        String district = addressBo.getDistrict();
        String detail = addressBo.getDetail();
        if (StringUtils.isBlank(province) ||
                StringUtils.isBlank(city) ||
                StringUtils.isBlank(district) ||
                StringUtils.isBlank(detail)) {
            return IMOOCJSONResult.errorMsg("收货地址信息不能为空");
        }

        return IMOOCJSONResult.ok();
    }


    private IMOOCJSONResult addressList(String userId,
                                      Throwable throwable) throws Exception {
        return IMOOCJSONResult.errorMsg("测试降级" + throwable.getLocalizedMessage());
    }
}
